﻿
#define FMT_HEADER_ONLY
#define FMT_UNICODE 0
#include <fmt/core.h>
#include <fmt/ranges.h>

#include "ASCII_Hex.hpp"

#include "url.h"

#include "yas/serialize.hpp"
#include "yas/std_types.hpp"

typedef std::vector<int32_t>     Integers;
typedef std::vector<std::string> Strings;

struct Record
{
    Integers ids;
    Strings  strings;

    template<typename Archive>
    void serialize(Archive& ar)
    {
        ar & strings & ids;
    }
};

void serialize_varray(const Record& record, std::vector<uint8_t>& data)
{
    yas::mem_ostream                             os;
    yas::binary_oarchive<yas::mem_ostream, yas::binary | yas::no_header> oa(os);
    oa & record;

    auto buf = os.get_intrusive_buffer();
    data.assign(buf.data, buf.data + buf.size);
}

void deserialize_varray(Record& record, const std::vector<uint8_t>& data)
{
    yas::mem_istream                             is(data.data(), data.size());
    yas::binary_iarchive<yas::mem_istream, yas::binary | yas::no_header> ia(is);
    ia & record;
}

//#include "nameof.hpp"

enum class Color
{
    RED   = 1,
    BLUE  = 2,
    GREEN = 4
};

int main()
{
    auto color = Color::RED;

    //fmt::print("{} {} = {}/{}\n", NAMEOF_TYPE_EXPR(color), NAMEOF(color).c_str(),
    //           nameof::nameof_enum(color), NAMEOF_ENUM(color));
    //
    //fmt::print("{}\n", NAMEOF(main).c_str());

    const std::string          kStringValue = "1234567890";
    const std::vector<int32_t> kIntegers    = {
        0x0,
        0x11223344,
        0x0,
        0x10,
    };

    std::vector<uint8_t> serialized;
    {
        Record r1;

        for (size_t i = 0; i < kIntegers.size(); i++)
        {
            r1.ids.push_back(kIntegers[i]);
        }

        for (size_t i = 0; i < 2; i++)
        {
            r1.strings.push_back(kStringValue);
        }

        serialize_varray(r1, serialized);
        fmt::print("yas: {}\n", cryptl::asciiHex(serialized));
        fmt::print("yas: {}\n", serialized);
    }
    {
        Record r2;
        deserialize_varray(r2, serialized);
    }

    std::vector<uint8_t> btext;
    cryptl::asciiHexToVector("112233", btext);

    fmt::print("{}\n", cryptl::asciiHex(btext));

    std::array<uint8_t, 8> bkey;
    cryptl::asciiHexToArray("1122334455667788", bkey);

    fmt::print("{}\n", cryptl::asciiHex(bkey));


    upa::url    url;
    std::string input = "https://user:pwd@example.com:8000/?id=1&utm_source=twitter.com&utm_medium=social";

    {
        if (upa::success(url.parse(input)))
        {
            fmt::print("     href: {}\n", std::string(url.href()));
            fmt::print("   origin: {}\n", std::string(url.origin()));
            fmt::print(" protocol: {}\n", std::string(url.protocol()));
            fmt::print(" username: {}\n", std::string(url.username()));
            fmt::print(" password: {}\n", std::string(url.password()));
            fmt::print(" hostname: {}\n", std::string(url.hostname()));
            fmt::print("     port: {}\n", std::string(url.port()));
            fmt::print(" pathname: {}\n", std::string(url.pathname()));
            fmt::print("   search: {}\n", std::string(url.search()));
            fmt::print("     hash: {}\n", std::string(url.hash()));
        }
        else
        {
            fmt::print(" URL parse error\n");
        }
    }

    {
        int ber_tlv();
        ber_tlv();
    }
}
